package com.b.btest;

import static com.b.btest.Constants.*;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Typeface;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.Html;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.b.btest.DetectableSoftKeyLayout.KeyboardListener;

/**
 *ThirdActivityクラス.
 *
 * @author Hidezi
 *
 */
public class ThirdActivity extends Activity implements OnClickListener, Runnable {

	
	/** enterボタン */
	private Button enter;
	/** withボタン */
	private Button with;
	/**imgbutton*/
	private ImageButton imgbutton;
	/** メディアプレーヤー */
	private MediaPlayer mp;
	/** メディアプレーヤーの再生状況 */
	int mpnow = 0;
	/** ポジション */
	int position;
	/** 終了フラグ */
	int fin = 0;
	/** withフラグ */
	int withFlg = 0;
	/** ソケット */
	private Socket socket;
	/** 入力ストリーム */
	private InputStream in;
	/** 出力ストリーム */
	private OutputStream out;
	/** ログインフラグ */
	private boolean doneLogin;
	/** 乱数 */
	private String strRand;
	/** 音楽パス */
	private String fmusicpath;
	/** 音楽タイトル */
	private String fmusicTitle;
	/** アーティスト */
	private String fmusicArtist;
	/** 相手のコード */
	private String aiteCode;
	/** 相手の乱数 */
	private String aiterand;
	/** 相手のアーティスト */
	private String aiteartist;
	/** 相手のタイトル */
	private String aitetitle;
	/** 相手のテキスト */
	private String aitetext;
	/** 自分の名前 */
	private String yourName = null;
	/** 相手の名前 */
	private String aiteName = null;
	/** ステータスを送ったフラグ */
	private int statusSendflg = 0;
	/** 終了メッセージ送付完了フラグ */
	//private int endFlg = 0;
	/** 自分のミュージックポジション */
	private String musicPosition;
	/** 相手のミュージックポジション */
	private String aitemusicPosition;
	/** 裏でhtml文を保持する */
	private String textBank = "";
	/** シークバー */
	private SeekBar seekBar;
	/** ログアウトしたかどうか */
	private boolean doneLogout = false;
	/** 改行 */
	private final static String BR = System.getProperty("line.separator");
	/** 曲のパスを表す文字列 */
	private final static String MUSIC_PATH_STR = "musicPath";
	/** 曲名を表す文字列 */
	private final static String MUSIC_TITLE_STR = "musicTitle";
	/** アーティストを表す文字列 */
	private final static String MUSIC_ARTIST_STR = "musicArtist";
	/**自分のテキスト色*/
	private String zibun_Text_Color;
	/**相手のテキスト色*/
	private String aite_Text_Color;
	/**通常のテキスト色*/
	private String use_Text_Color;
	/**自分のテキスト色HTML用*/
	private String zibun_Text_Color_HTML;
	/**相手のテキスト色HTML用*/
	private String aite_Text_Color_HTML;
	/**通常のテキスト色HTML用*/
	private String use_Text_Color_HTML;
	/**ソフトキーボード制御用*/
	private DetectableSoftKeyLayout layout;

	/** ハンドラ */
	private final Handler handler = new Handler();

	/** SE用*/
	private SoundPool sp;
	int seID_Start = -1;
	int seID_With = -1;
	
	/** Animation用**/
	private AnimationSet setKaiten;

	/**
	 * onCreate.
	 *
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_third);

		//リソースファイルからSEをロード
		sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
		seID_Start = sp.load(this, R.raw.start, 1);
		seID_With = sp.load(this, R.raw.with, 1);

		//メディアプレーヤー
		mp = new MediaPlayer();

		//文字等背景の設定
		backGroundSetting();

		//インテント
		Intent intent = getIntent();
		if (intent != null) {
			// 曲のパスを取得
			final String fmusicPath = intent.getStringExtra(MUSIC_PATH_STR);
			// 曲名を取得
			fmusicTitle = intent.getStringExtra(MUSIC_TITLE_STR);
			// アーティスト名を取得
			fmusicArtist = intent.getStringExtra(MUSIC_ARTIST_STR);

			// 画面に曲名用のテキストビューを取得
			TextView musicName = (TextView) findViewById(R.id.musicname);
			// 画面にアーティスト名用のテキストビューを取得
			TextView artistName = (TextView) findViewById(R.id.artistname);
			// enterボタンを取得
			enter = (Button) findViewById(R.id.enter);
			// シークバーを取得
			seekBar = (SeekBar) findViewById(R.id.seekBar1);
			// withボタンを取得
			with = (Button) findViewById(R.id.with);
			//imageViewbuttonを取得
			imgbutton = (ImageButton)findViewById(R.id.imageView1);
			

			// インテントされた曲名をテキストビューに表示
			musicName.setText(fmusicTitle);
			// インテントされたアーティスト名をテキストビューに表示
			artistName.setText(fmusicArtist);
			// enterボタンクリックリスナー
			enter.setOnClickListener(this);
			// withボタンクリックリスナー
			with.setOnClickListener(this);
			//imageView1buttonクリックリスナー
			imgbutton.setOnClickListener(this);

			fmusicpath = fmusicPath;

			//fromhtml用に色変換
			fromHTML_Color_Change();

			//ソフトキーボード制御のため
			DetectableSoftKeyLayout root = (DetectableSoftKeyLayout) findViewById(R.id.root);
			root.setKeyboardListener(new KeyboardListener() {
				public void onKeyboardShown() {
					ScrollView scrollView1 = (ScrollView) findViewById(R.id.scrollView1);
					scrollView1.fullScroll(ScrollView.FOCUS_DOWN);
				}

				public void onKeyboardHidden() {
					new Handler().postDelayed(delayFunc, 400);
					new Handler().postDelayed(delayFunc, 700);
				}
			});

			// スレッドの生成
			Thread thread = new Thread() {
				public void run() {
					try {
						// 名前の生成
						strRand = createRandomStr();
						connect(InetAddress.getByName(DOMAIN).getHostAddress(), PORT);
					} catch (Exception e) {
					}
				}
			};
			// スレッド開始
			thread.start();
		}
		// 相手のステータスを表示
		TextView aitestatus = (TextView) findViewById(R.id.aitestatus);
		//瀬戸フォントを指定。
		aitestatus.setTypeface(Typeface.createFromAsset(getAssets(),
				"setofont.ttf"));
		//色を指定
		aitestatus.setTextColor(Color.parseColor(use_Text_Color));
		aitestatus.setText("    フェネックボタンを押してください");
		// シークバーのリスナー
		seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
			/**
			 * つまみ変更時.
			 */
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
			}

			/**
			 * つまみにタッチしたときの処理.
			 */
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			/**
			 * つまみを離したときの処理.
			 */
			public void onStopTrackingTouch(SeekBar seekBar) {
				int nextMpPosition = seekBar.getProgress();
				mp.seekTo(nextMpPosition);
			}
		});
	}

	/**
	 * アクティビティ開始時に呼ばれる.
	 */
	@Override
	public void onStart() {
		super.onStart();
		
		//回転登場アニメーション
		AnimationSet set = new AnimationSet(true);
		RotateAnimation rotate = new RotateAnimation(0, 360, imgbutton.getWidth()/2, imgbutton.getHeight()/2); // imgの中心を軸に、0度から360度にかけて回転
		set.addAnimation(rotate);
		TranslateAnimation translate = new TranslateAnimation(-500, 0, 0, 0); // 移動
		set.addAnimation(translate);
		set.setDuration(1000); // 1000msかけてアニメーションする
		imgbutton.startAnimation(set); // アニメーション適用
	}

	/**
	 * アクティビティの停止時に呼ばれる.
	 */
	@Override
	public void onStop() {
		super.onStop();
	}

	/**
	 * アクティビティ終了時に呼ばれる.
	 */
	public void onDestoroy() {
		super.onDestroy();
		disconnect();
		sp.stop(seID_Start);
		sp.stop(seID_With);
		sp.unload(seID_Start);
		sp.unload(seID_With);
		sp.release();

	}

	/**
	 * 受信テキストの追加.
	 *
	 * @param text
	 */
	private void addText(final String text) {
		// ハンドラの生成
		handler.post(new Runnable() {
			public void run() {
				TextView textView1 = (TextView) findViewById(R.id.textView1);
				ScrollView scrollView1 = (ScrollView) findViewById(R.id.scrollView1);
				textView1.setTypeface(Typeface.createFromAsset(getAssets(),
						"setofont.ttf"));

				// HTML タグ付き文字列の作成
				String htmlText = "<BR><font color=\"" + use_Text_Color_HTML + "\">" + text + "</font>";
				textBank = textBank + htmlText;
				// fromHtml() の引数にタグ付き文字列を渡す
				CharSequence source = Html.fromHtml(textBank);
				textView1.setText(source);
				scrollView1.fullScroll(ScrollView.FOCUS_DOWN);

			}
		});
	}

	/**
	 * 相手からの受信テキストの追加.
	 *
	 * @param text
	 */
	private void addRecieveText(final String text) {
		// ハンドラの生成
		handler.post(new Runnable() {
			public void run() {
				TextView textView1 = (TextView) findViewById(R.id.textView1);
				ScrollView scrollView1 = (ScrollView) findViewById(R.id.scrollView1);
				textView1.setTypeface(Typeface.createFromAsset(getAssets(),
						"setofont.ttf"));

				// HTML タグ付き文字列の作成
				String htmlText = "<BR><font color=\"" + aite_Text_Color_HTML + "\">" + text + "</font>";
				textBank = textBank + htmlText;
				// fromHtml() の引数にタグ付き文字列を渡す
				CharSequence source = Html.fromHtml(textBank);
				textView1.setText(source);
				scrollView1.fullScroll(ScrollView.FOCUS_DOWN);
			}
		});
	}

	/**
	 * 自分からの受信テキストの追加.
	 *
	 * @param text
	 */
	private void addRecieveMyText(final String text) {
		// ハンドラの生成
		handler.post(new Runnable() {
			public void run() {
				TextView textView1 = (TextView) findViewById(R.id.textView1);
				ScrollView scrollView1 = (ScrollView) findViewById(R.id.scrollView1);
				textView1.setTypeface(Typeface.createFromAsset(getAssets(),
						"setofont.ttf"));

				// HTML タグ付き文字列の作成
				String htmlText = "<BR><font color=\"" + zibun_Text_Color_HTML + "\">" + text + "</font>";
				textBank = textBank + htmlText;
				// fromHtml() の引数にタグ付き文字列を渡す
				CharSequence source = Html.fromHtml(textBank);
				textView1.setText(source);
				scrollView1.fullScroll(ScrollView.FOCUS_DOWN);
			}
		});
	}

	/**
	 * 相手ステータスの表示.
	 */
	private void settingText() {
		// ハンドラの生成
		handler.post(new Runnable() {
			public void run() {
				if (!strRand.equals(aiterand)) {
					// 相手のステータスを表示
					TextView aitestatus = (TextView) findViewById(R.id.aitestatus);
					// アーティストと曲名が一致した場合
					if (aitetitle.equals(fmusicTitle) && aiteartist.equals(fmusicArtist)) {
						aitestatus
								.setText("話し相手は、同じ曲 " + aitetitle + " / " + aiteartist + "を聴いている " + BR + " ☞  "
										+ aiteName);
					}
					// アーティストが一致した場合
					else if (aiteartist.equals(fmusicArtist)) {
						aitestatus.setText("話し相手は、同じアーティスト 『" + aitetitle + " / " + aiteartist + "』 を聴いている " + BR
								+ " ☞  "
								+ aiteName);
					}
					// 曲名が一致した場合
					else if (aitetitle.equals(fmusicTitle)) {
						aitestatus.setText("話し相手は、同じ名前の曲 『" + aitetitle + " / " + aiteartist + "』 を聴いている " + BR
								+ " ☞  "
								+ aiteName);
					}
					// それ以外の場合
					else {
						aitestatus
								.setText("話し相手は、近い曲 『" + aitetitle + " / " + aiteartist + "』 を聴いている " + BR + " ☞  "
										+ aiteName);
					}
				}
			}
		});
	}

	/**
	 * 接続.
	 *
	 * @param ip
	 * @param port
	 */
	private void connect(String ip, int port) {
		int size;
		String str;
		byte[] w = new byte[BUFFER_SIZE];
		try {
			// ソケット接続
			addText("ステーションに接続中... ");

			socket = new Socket(ip, port);

			// タイムアウトを設定
			socket.setSoTimeout(READ_TIMEOUT_TIME);
			in = socket.getInputStream();
			out = socket.getOutputStream();

			addText("ステーションに接続完了!! " + BR);

			// ログインフラグを初期化
			doneLogin = false;

			// 受信ループ
			while (socket != null && socket.isConnected()) {

				// データの受信
				size = in.read(w);
				if (size <= 0)
					continue;
				str = new String(w, 0, size, MESSAGE_ENCODE);

				// 文字列変換
				getInfoFromStr(str);

				// 識別子によって処理を振り分け
				switch (Identifer.toIdentifer(aiteCode)) {
				case LOGIN:
					countedMessage();
					break;
				case STATUS:
					statusLogic();
					break;
				case LOGOUT_RECOMMEND:
					logoutRecommendLogic();
					break;
				case REQUEST_SYNCRO_MUSIC:
					requestSyncroMusicLogic();
					break;
				case SYNCRO_MUSIC:
					syncroMusicLogic();
					break;
				case SEND:
					sendLogic();
					break;
				default:
					// 想定外の識別子の場合、何もしない
					break;
				}
			}
		} catch (SocketTimeoutException timeoutEx) {
			// ソケットがタイムアウトした場合ログアウト
			sekainoOwari();
		} catch (Exception e) {
			addText("通信が切断されました");
			System.out.println(e.getStackTrace().toString());
		}
	}

	/**
	 * 識別子がSTATUSの場合の処理.
	 *
	 */
	private void statusLogic() {
		// 相手からステータスのみ送付で、こちらがステータスを送ったことがない場合
		if (!aiterand.equals(strRand) && statusSendflg == 0) {
			if (aitetext == null) {
				// 相手の名前変換
				NameAdd na = new NameAdd();
				aiteName = na.aiteNameadd(aiterand);
			}
			else {
				aiteName = aitetext;
			}
			// 相手のステータスを表示
			settingText();

			// ステータスを送る
			sendStatus();
			// ステータスを送ったフラグを１にする
			statusSendflg = 1;
		}
		// 相手からステータスのみ送付で、すでにこちらがステータスを送ったことがある場合
		else if (!aiterand.equals(strRand)) {

			if (aitetext == null) {
				// 相手の名前変換
				NameAdd na = new NameAdd();
				aiteName = na.aiteNameadd(aiterand);
			}
			else {
				aiteName = aitetext;
			}
			// 相手のステータスを表示
			settingText();
		}
		// 自分からステータスのみ送付の場合
		else {
			// 何もしない
		}
	}

	/**
	 * 識別子がLOGOUT_RECOMMENDの場合の処理.
	 *
	 */
	private void logoutRecommendLogic() {
		// 自分からの終了メッセージを受け取った場合
		if (aiterand.equals(strRand)) {
			doneLogout = true;
			addText(aiteName + "はログアウトしました。");
		}
		// 相手からの終了メッセージを受け取った場合
		else {
			addText(aiteName + "は帰りました。");
			// 相手のステータスを名前空白にして表示
			aiteName = "";
			settingText();
			statusSendflg = 0;
		}
	}

	/**
	 * 識別子がREQUEST_SYNCRO_MUSICの場合の処理.
	 *
	 */
	private void requestSyncroMusicLogic() {
		// 相手のwithボタンが押された場合
		if (!strRand.equals(aiterand) && aiteartist.equals(fmusicArtist) && aitetitle.equals(fmusicTitle)) {
			// 自分のミュージックポジションを送付
			musicPosition = String.valueOf(mp.getCurrentPosition());
			sendmusicPosition(musicPosition);
		}
		else {
			//何もしない
		}
	}

	/**
	 * 識別子がSYNCRO_MUSICの場合の処理.
	 *
	 */
	private void syncroMusicLogic() {
		// 相手からミュージックポジションを受け取る場合
		if (!strRand.equals(aiterand)) {
			if (aitetitle.equals(fmusicTitle) && aiteartist.equals(fmusicArtist)) {
				aitemusicPosition = aitetext;
				// 相手のミュージックポジションを取得
				int aitempPosition = Integer.parseInt(aitemusicPosition);
				// 自分の再生曲の全体の長さを取得
				int mympDuration = mp.getDuration();
				// 自分の再生曲の全体の長さが相手のミュージックポジションより長ければ同期
				if (mympDuration > aitempPosition) {
					mp.seekTo(aitempPosition);
				}
				else {
					mp.seekTo(0);
				}
				//メッセージを送付
				// スレッドの生成
				Thread thread = new Thread(new Runnable() {
					boolean error;

					public void run() {
						error = false;
						try {
							// データの送信
							if (socket != null && socket.isConnected()) {
								byte[] w;
								w = normalSend(strRand, fmusicArtist, fmusicTitle, withMessage)
										.getBytes(MESSAGE_ENCODE);
								out.write(w);
								out.flush();
							}
						} catch (Exception e) {
							error = true;
						}

					}
				});
				thread.start();
			}
			else {
				// テキストビューへの文字列追加
				addRecieveText(aitetext + " (" + aiteName + ")");
			}
		}
		// 自分のミュージックポジションが返ってきた場合
		else {
			// 何もしない
		}
	}

	/**
	 * 識別子がSENDの場合の処理.
	 *
	 */
	private void sendLogic() {
		//自分か話し相手かで色を分ける
		if (strRand.equals(aiterand)) {
			addRecieveMyText(aitetext + " (" + yourName + ")");
		}
		else {
			addRecieveText(aitetext + " (" + aiteName + ")");
		}
	}

	/**
	 * 識別子がLOGINの場合の処理.
	 *
	 */
	private void countedMessage() {
		addText("フェネックボタンを押したときの、<br>" + aitetext + "<br><br>");
	}


	/**
	 * 文字列から必要な情報を取得.<br>
	 * splitで区切り文字をヒントに必要なデータを取得する.
	 */
	private void getInfoFromStr(String str) {
		String[] aitestr = str.split(",", 0);
		aiteCode = aitestr[0];
		aiterand = aitestr[1];
		aiteartist = aitestr[2];
		aitetitle = aitestr[3];
		aitetext = aitestr[4];
	}

	/**
	 * 切断.
	 */
	private void disconnect() {
		try {
			socket.close();
			socket = null;
		} catch (Exception e) {
		}
	}

	/**
	 * ボタンクリックイベントの処理.
	 */
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.imageView1:
			//接続が成功している場合は再生開始。していない場合はトースト表示。
			if (socket != null && socket.isConnected()) {
				// 再生ボタンが押されている場合、停止して▶ボタンを表示
				if (mp.isPlaying()) {
					mp.pause();
					mpnow = 1;
					
					//アニメーションの停止
					imgbutton.clearAnimation();
					
					
				}
				// 停止ボタンが押されている場合、再生して■ボタンを表示
				else if (mpnow == 1) {
					mp.start();
					
					
					//回転アニメーションの開始
					setKaiten = new AnimationSet(true);
					RotateAnimation rotate = new RotateAnimation(0, 360, imgbutton.getWidth()/2, imgbutton.getHeight()/2); // imgの中心を軸に、0度から360度にかけて回転
					rotate.setDuration(5000); // 5000msかけてアニメーションする
					rotate.setRepeatCount(Animation.INFINITE);
					setKaiten.addAnimation(rotate);
					imgbutton.startAnimation(rotate); // アニメーション適用
					
					
				}
				// 一度もボタンが押されたことがない場合
				else {
					try {
						//効果音を鳴らす
						sp.play(seID_Start, 1.0F, 1.0F, 0, 0, 1.0F);
						
					
						//回転アニメーションの開始
						setKaiten = new AnimationSet(true);
						RotateAnimation rotate = new RotateAnimation(0, 360, imgbutton.getWidth()/2, imgbutton.getHeight()/2); // imgの中心を軸に、0度から360度にかけて回転
						rotate.setDuration(5000); // 5000msかけてアニメーションする
						rotate.setRepeatCount(Animation.INFINITE);
						setKaiten.addAnimation(rotate);
						imgbutton.startAnimation(rotate); // アニメーション適用

						mp.setDataSource(fmusicpath);
						mp.setLooping(true);
						mp.prepare();
						mp.start();

						// 相手のステータスを表示
						TextView aitestatus = (TextView) findViewById(R.id.aitestatus);
						aitestatus.setText("    話し相手が来るのをまっています...");
						//テキストビューをクリアし、接続完了等のメッセージを見えなくする。
						textBank = "";
						// シークバーをセット
						seekBar.setProgress(0);
						seekBar.setMax(mp.getDuration());
						new Thread(this).start();

						//SharedPreferencesの値が存在する場合、HNを読み出して設定
						SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
						if (sp.contains("handle_name_string") == true) {

							//SharedPreferencesのHNを読み出して送付
							yourName = sp.getString("handle_name_string", null).toString();

							//yourNameが空白だった場合
							if (yourName.equals("")) {

								// 名前を授ける処理をおこなう
								NameAdd na = new NameAdd();
								yourName = na.yourNameadd(strRand);
								// 名前の表示
								Toast.makeText(this, "『" + yourName + "』" + "の名を授けられました。ハンドルネームは設定画面で設定できます。"
										, Toast.LENGTH_LONG).show();
							}
						}
						else {

							// 名前を授ける処理をおこなう
							NameAdd na = new NameAdd();
							yourName = na.yourNameadd(strRand);

							// 名前の表示
							Toast.makeText(this, "『" + yourName + "』" + "の名を授けられました。ハンドルネームは設定画面で設定できます。"
									, Toast.LENGTH_LONG).show();

						}

						// ------------------------
						// --------Login--------
						// ------------------------

						// テキストフォームを取得
						EditText editText1 = (EditText) findViewById(R.id.handle_name);
						try {
							// データの送信
							if (socket != null && socket.isConnected()) {
								byte[] w;
								if (!doneLogin) {
									w = login(strRand, fmusicArtist, fmusicTitle, editText1.getText().toString())
											.getBytes(
													MESSAGE_ENCODE);
									doneLogin = true;
									out.write(w);
									out.flush();

								}
							}
						} catch (Exception e) {
						}

					} catch (Exception e) {
						System.out.println(e.getStackTrace().toString());
					}
					// ステータスを送付
					sendStatus();
				}
			}
			else {
				Toast.makeText(this, "接続がまだ確立されていません。", Toast.LENGTH_SHORT).show();
			}

			break;

		// Enterボタンを押下した際の処理
		case R.id.enter:
			// テキストフォームを取得
			EditText editTexttest = (EditText) findViewById(R.id.handle_name);
			// テキストフォームから値を取得
			String edt = editTexttest.getText().toString();
			// あなたの名前が存在する、かつ、テキストフォームに値が存在する場合
			if (!isNullOrEmpty(yourName) && !isNullOrEmpty(edt)) {
				// ------------------------
				// --------SendMsg--------
				// ------------------------
				// スレッドの生成
				Thread thread = new Thread(new Runnable() {
					EditText editText1 = (EditText) findViewById(R.id.handle_name);
					private String et1 = editText1.getText().toString();
					private String et2 = toHtmlString(et1);

					boolean error;

					public void run() {
						error = false;
						try {
							// データの送信
							if (socket != null && socket.isConnected()) {
								byte[] w;
								w = normalSend(strRand, fmusicArtist, fmusicTitle, et2)
										.getBytes(MESSAGE_ENCODE);
								out.write(w);
								out.flush();
							}
						} catch (Exception e) {
							error = true;
						}
						// ハンドラの生成
						handler.post(new Runnable() {
							public void run() {
								if (!error) {
									editText1.setText("");
								} else {
									addText("通信失敗しました");
								}
							}
						});
					}
				});
				thread.start();
			}
			else if (isNullOrEmpty(yourName)) {
				Toast.makeText(this, "フェネックボタンを押してください。", Toast.LENGTH_SHORT).show();
			}

			else if (isNullOrEmpty(edt)) {
				Toast.makeText(this, "メッセージを入力してください。", Toast.LENGTH_SHORT).show();
			}

			//キーボードを隠す
			InputMethodManager inputMethodManager =
					(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);

			break;

		// withボタンが押されたときの処理
		case R.id.with:
			if (isNullOrEmpty(yourName)) {
				Toast.makeText(this, "フェネックボタンを押してください。", Toast.LENGTH_SHORT).show();
			}
			else {
				//効果音を鳴らす
				sp.play(seID_With, 1.0F, 1.0F, 0, 0, 1.0F);
				addText("<BR>" + yourName + "は、withbuttonを押しました。同じ曲以外は無効です。");
				withFlg = 1;
				sendWith();
			}
			break;
		}
	}

	/**
	 * バックボタンを押下した際の処理
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {

		if (keyCode == KeyEvent.KEYCODE_BACK) {
			// 確認ダイアログを表示
			yesNo();
			return true;
		}
		return false;
	}

	/**
	 * ログイン
	 *
	 */
	private String login(String name, String artist, String music, String msg) {
		return createSendStr(Identifer.LOGIN.toString(), name, artist, music, msg);
	}

	/**
	 * ログアウト
	 *
	 */
	private String logout(String name, String artist, String music, String msg) {
		return createSendStr(Identifer.LOGOUT.toString(), name, artist, music, msg);
	}

	/**
	 * 通常メッセージ送信
	 *
	 */
	private String normalSend(String name, String artist, String music, String msg) {
		return createSendStr(Identifer.SEND.toString(), name, artist, music, msg);
	}

	/**
	 * その他のメッセージ送信
	 *
	 */
	private String otherSend(String code, String name, String artist, String music, String msg) {
		return createSendStr(code, name, artist, music, msg);
	}

	/**
	 * メッセージ生成
	 *
	 */
	private String createSendStr(String key, String name, String artist, String music, String msg) {
		// ヘッダー生成
		return removeUnitStr(key) + "," + removeUnitStr(name) + ","
				+ removeUnitStr(artist) + "," + removeUnitStr(music) + "," + removeUnitStr(msg);
	}

	/**
	 * 結合文字列の除去
	 *
	 */
	private String removeUnitStr(String str) {
		return str.replaceAll(",", "");
	}

	/**
	 * 乱数生成
	 *
	 */
	private String createRandomStr() {
		// 最大桁数
		final int MAX_DIGIT = 64;
		String str = new String();
		for (int i = 0; i < MAX_DIGIT; i++) {
			// 考え方 1+2=12
			str += String.valueOf((int) (Math.random() * 10));
		}

		return str;
	}

	/**
	 * 確認ダイアログ
	 *
	 */
	private void yesNo() {
		// 確認ダイアログの生成
		AlertDialog.Builder alertDlg = new AlertDialog.Builder(this);
		alertDlg.setTitle("確認");
		alertDlg.setMessage("同じ曲を聴き、同じ話をするのをやめますか？");
		alertDlg.setPositiveButton(
				"OK",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						// OK ボタンクリック処理
						mp.stop();
						mp.release();
						mp = null;
						sekainoOwari();
					}
				});
		alertDlg.setNegativeButton(
				"キャンセル",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						// Cancel ボタンクリック処理
					}
				});
		// ダイアログの表示
		alertDlg.create().show();
	}

	/**
	 * 終了処理
	 *
	 */
	private void sekainoOwari() {
		if (doneLogin) {
			// ------------------------
			// --------Logout--------
			// ------------------------
			//終了メッセージを送付
			sendEnd();
			EditText editText1 = (EditText) findViewById(R.id.handle_name);
			try {
				// データの送信
				if (socket != null && socket.isConnected()) {
					byte[] w;
					w = logout(strRand, fmusicArtist, fmusicTitle, editText1.getText().toString()).getBytes(
							MESSAGE_ENCODE);
					doneLogin = false;
					out.write(w);
					out.flush();
				}
			} catch (Exception e) {
			}

			try {
				// 5秒間0.1秒刻みでサーバからのログアウトメッセージを元にしたログアウトしたかのフラグを判定
				// 5秒間ログアウトが確認できなければ強制的にアクティビティを終了させる
				int count = 0;
				while (count < 50) {
					if (doneLogout) {
						// アクティビティの終了
						this.finish();
						break;
					}
					Thread.sleep(100);
					count++;
				}

				// アクティビティの終了
				disconnect();
				this.finish();
			} catch (InterruptedException e) {
			}
		}
		else {
			// アクティビティの終了
			disconnect();
			this.finish();
		}
	}

	/**
	 * nullまたはEmptyかどうか.
	 *
	 * @param str
	 * @return true or false
	 */
	private boolean isNullOrEmpty(String str) {
		if (str == null || str.equals("")) {
			return true;
		}
		return false;
	}

	/**
	 * シークバーのrun
	 *
	 */
	public void run() {
		int currentPosition = 0;
		int total = mp.getDuration();
		while (mp != null && currentPosition < total) {
			try {
				Thread.sleep(1000);
				currentPosition = mp.getCurrentPosition();
			} catch (InterruptedException e) {
				return;
			} catch (Exception e) {
				return;
			}
			seekBar.setProgress(currentPosition);
		}
	}

	/**
	 * ステータスを送付
	 *
	 */
	public void sendStatus() {
		sendSpecialMsg(Identifer.STATUS.toString(), yourName);
	}

	/**
	 * 終了メッセージを送付
	 *
	 */
	public void sendEnd() {
		sendSpecialMsg(Identifer.LOGOUT_RECOMMEND.toString(), "終了メッセージを送付");
	}

	/**
	 * withメッセージを送付
	 *
	 */
	public void sendWith() {
		sendSpecialMsg(Identifer.REQUEST_SYNCRO_MUSIC.toString(), "withメッセージを送付");
	}

	/**
	 * ミュージックポジションの送付
	 *
	 */
	public void sendmusicPosition(String musicPosiｔion) {
		sendSpecialMsg(Identifer.SYNCRO_MUSIC.toString(), musicPosition);
	}

	/**
	 * 特殊メッセージの送信
	 *
	 */
	public void sendSpecialMsg(String specialCode, String specialStr) {
		// ------------------------
		// --------SendMsg--------
		// ------------------------
		try {
			// データの送信
			if (socket != null && socket.isConnected()) {
				byte[] w;
				w = otherSend(specialCode, strRand, fmusicArtist, fmusicTitle, specialStr)
						.getBytes(MESSAGE_ENCODE);
				out.write(w);
				out.flush();
			}
		} catch (Exception e) {
		}
	}

	/**
	 * ソフトキーボード収納完了後の遅滞スクロールダウン
	 *
	 */
	private final Runnable delayFunc = new Runnable() {
		public void run() {
			ScrollView scrollView1 = (ScrollView) findViewById(R.id.scrollView1);
			scrollView1.fullScroll(ScrollView.FOCUS_DOWN);
		}
	};

	/**
	 * 文字等の背景設定
	 *
	 */
	public void backGroundSetting() {
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
		zibun_Text_Color = (sp.getString("zibun_text_color", DEF_ZIBUN_TEXT_COLOR));
		aite_Text_Color = (sp.getString("aite_text_color", DEF_AITE_TEXT_COLOR));
		use_Text_Color = (sp.getString("use_text_color", DEF_USE_TEXT_COLOR));

	}

	/**
	 * HTMLエスケープ出力データコンバート
	 *
	 * @param pData 変換文字列
	 * @return 文字列
	 */
	public String toHtmlString(String pData) {
		String s = "";
		for (int i = 0; i < pData.length(); i++) {
			Character c = new Character(pData.charAt(i));
			switch (c.charValue()) {
			case '&':
				s = s.concat("&amp;");
				break;
			case '<':
				s = s.concat("&lt;");
				break;
			case '>':
				s = s.concat("&gt;");
				break;
			case '"':
				s = s.concat("&quot;");
				break;
			case '\'':
				s = s.concat("&#39;");
				break;
			case '\n':
				s = s.concat("<BR>");
				break;
			default:
				s = s.concat(c.toString());
				break;
			}
		}
		return s;
	}

	/*
	 * Fromhtml用の色変換
	 *
	 */
	public void fromHTML_Color_Change(){
		zibun_Text_Color_HTML = zibun_Text_Color;
		aite_Text_Color_HTML = aite_Text_Color;
		use_Text_Color_HTML = use_Text_Color;


		if(zibun_Text_Color_HTML.equals("CYAN")){
			zibun_Text_Color_HTML = "Aqua";
		}
		else if(zibun_Text_Color_HTML.equals("MAGENTA")){
			zibun_Text_Color_HTML = "Fuchsia";
		}
		else if(zibun_Text_Color_HTML.equals("GRAY")){
			zibun_Text_Color_HTML = "Grey";
		}
		else{
		}
		if(aite_Text_Color_HTML.equals("CYAN")){
			aite_Text_Color_HTML = "Aqua";
		}
		else if(aite_Text_Color_HTML.equals("MAGENTA")){
			aite_Text_Color_HTML = "Fuchsia";
		}
		else if(aite_Text_Color_HTML.equals("GRAY")){
			aite_Text_Color_HTML = "Grey";
		}
		else{
		}
		if(use_Text_Color_HTML.equals("CYAN")){
			use_Text_Color_HTML = "Aqua";
		}
		else if(use_Text_Color_HTML.equals("MAGENTA")){
			use_Text_Color_HTML = "Fuchsia";
		}
		else if(use_Text_Color_HTML.equals("GRAY")){
			use_Text_Color_HTML = "Grey";
		}
		else{
		}

	}
}
